use std::fmt::Debug;

trait Chain<T: Debug> {
    fn exec(&self, ctx: &mut Context<T>) -> bool;
}

type Handle<T> = fn(&mut Context<T>) -> bool;

#[derive(Debug)]
struct ChainItem<T> {
    handle: Handle<T>,
}

impl<T: Debug> Chain<T> for ChainItem<T> {
    fn exec(&self, ctx: &mut Context<T>) -> bool {
        (self.handle)(ctx)
    }
}

#[derive(Debug)]
struct Context<T> {
    resp: T,
}

impl<T: Debug> Context<T> {
    fn exec(&mut self, chains: Vec<Box<dyn Chain<T>>>) {
        chains.iter().for_each(|x| {
            x.exec(self);
        })
    }
}

#[test]
fn text() {
    let context = &mut Context { resp: "string" };
    println!("{:?}", context);
    let item: Box<dyn Chain<&str>> = Box::new(ChainItem {
        handle: |ctx: &mut Context<&str>| {
            ctx.resp = "asdasdsda";
            return false;
        },
    });
    item.exec(context);
    let vec1 = vec![item];
    context.exec(vec1);
    println!("{:?}", context);
}